<template>
  <div class="app-drawer">
    <el-drawer
      class="drawerWithButton"
      :title="textMap[dialogStatus]"
      :append-to-body="true"
      :lock-scroll="false"
      :visible.sync="drawer"
      :direction="direction"
      :before-close="handleClose"
      :wrapper-closable="false"
      :size="size"
    >
      <div class="roleInfo">
        <div class="titleBox">
          <div class="title-text"> <i class="title-icon el-icon-folder-opened" :style="{'--themecolor':themeActive}" />基本信息</div>
        </div>
        <DtForm
          :form-opts="config"
          :width-size="2"
          :ref-obj.sync="config.ref"
          @handleEvent="handleEvent"
        />
      </div>
      <div class="roleInfo">
        <div class="titleBox">
          <div class="title-text"><i class="title-icon el-icon-notebook-2" :style="{'--themecolor':themeActive}" />角色权限</div>
          <el-button type="text" :icon="activePermission == false?'el-icon-arrow-down':'el-icon-arrow-up'" @click="permissionUpDown(activePermission)">{{ activePermission == false?'收起':'展开' }}</el-button>
        </div>
        <div v-show="activePermission == false">
          <el-tabs v-model="activeName" type="border-card" style="margin-bottom: 24px;">
            <el-tab-pane label="功能权限" name="1">
              <dtSelectApply
                ref="treeTransfer"
                v-model="selectNodeIds"
                :default-props="defaultProps"
                :column-props="columnProps"
                :api="api"
                :select-data="selectData"
                :span-show="false"
                @getChecked="handleGetChecked"
              />
            </el-tab-pane>
          </el-tabs>
        </div>
      </div>
      <div class="roleInfo">
        <div class="titleBox">
          <div class="title-text"><i class="title-icon el-icon-setting" :style="{'--themecolor':themeActive}" />数据范围</div>
          <div v-if="config.formData.scopeType == 4">
            <el-button type="text" :icon="activeScope == false?'el-icon-arrow-down':'el-icon-arrow-up'" @click="scopeUpDown(activeScope)">{{ activeScope == false?'收起':'展开' }}</el-button>
          </div>
        </div>
        <div v-show="!(activeScope == true &&config.formData.scopeType == 4)">
          <el-radio-group v-model="config.formData.scopeType" @change="changeRadio(config.formData.scopeType)">
            <el-radio
              v-for="dict in dict.type.orgType"
              :key="dict.value"
              border
              :label="parseInt(dict.value)"
            >所属{{ dict.label }}</el-radio>
            <el-radio
              v-for="dict in dict.type.orgType.filter(item=>{return item.value == '2'})"
              :key="dict.value?'3':''"
              border
              :label="parseInt(dict.value?'3':'')"
            >{{ '所属'+dict.label+'及以下' }}</el-radio>
            <el-radio
              :key="'4'"
              border
              :label="4"
            >指定部门</el-radio>
          </el-radio-group>
          <div v-if="config.formData.scopeType == 1" class="scope-remark">表示绑定了该角色的用户的数据范围是用户所属公司及以下</div>
          <div v-if="config.formData.scopeType == 2" class="scope-remark">表示绑定了该角色的用户的数据范围是用户所属部门</div>
          <div v-if="config.formData.scopeType == 3" class="scope-remark">表示绑定了该角色的用户的数据范围是用户所属部门及其子部门</div>
          <div v-if="config.formData.scopeType == 4" class="scope-remark">指定部门的数据范围，由管理员的可授权范围决定</div>
          <div v-if="config.formData.scopeType == 4" class="selectOrg">
            <dtSelectOrg
              ref="orgPicker"
              v-model="config.formData.grantOrgScopeIds"
              :span-show="false"
              :default-props="defaultProps"
              :column-props="scopeColumnProps"
              :api="orgApi"
              :tag-visible="false"
              :select-data="selectedOrg"
              @input="handleInput"
            />
          </div>
        </div>
      </div>
      <div class="el-drawer__footer">
        <el-button size="small" @click="handleClose">取消</el-button>
        <el-button v-preventReClick="3000" type="primary" size="small"
                   @click="submitForm">保存</el-button>
      </div>
    </el-drawer>
  </div>
</template>
<script>
import { userDetail, getCurrAdminGroupApps, addRole, updateRole, getParentGroupFunction, getRoleFunctionChooseTree, getParentGroupDataScope } from '@/framework/api/authCenter/bussinessRoleManage'
import { uuId } from '@/framework/utils/uuid'
import { checkCode, checkAccountName } from '@/framework/utils/validate'
import dtSelectOrg from '@/framework/components/addPerson/dt-select-org'
import dtSelectApply from '@/framework/components/addPerson/dt-select-apply.vue'

export default {
  name: 'BussinessRoleEdit',
  components: { dtSelectOrg, dtSelectApply },
  dicts: ['orgType'],
  props: {
    appList: {
      type: Array,
      default() {
        return []
      }
    }
  },
  data() {
    return {
      defaultProps: {
        children: 'children',
        label: 'name',
        id: 'id'
      },
      columnProps: {
        followApp: '',
        roleType: 1,
        roleId: ''
      },
      api: { getParentGroupFunction },
      orgApi: { getParentGroupDataScope },
      scopeColumnProps: {
        roleId: '',
        orgName: '',
        orgId: '-1'
      },
      drawer: false,
      direction: 'rtl',
      size: '50%',
      activePermission: false,
      activeScope: false,
      dialogStatus: '',
      textMap: {
        update: '修改角色',
        create: '新增角色',
        copy: '复制角色'
      },
      activeName: '1',
      grantAppIds: [],
      grantMenuCodes: [],
      grantMenuButtonCodes: [],
      grantFuncionCodes: [],
      config: {
        ref: null,
        labelWidth: '90px',
        formData: {
          roleCode: '',
          roleName: '',
          roleType: 1,
          followApp: '',
          remark: '',
          scopeType: 2,
          grantAppIds: '',
          grantMenuCodes: '',
          grantMenuButtonCodes: '',
          grantFuncionCodes: '',
          grantOrgScopeIds: ''
        },
        columns: [
          {
            label: '角色编码',
            prop: 'roleCode',
            type: 'text',
            component: 'el-input',
            maxlength: 15
          },
          {
            label: '角色名称',
            prop: 'roleName',
            type: 'text',
            component: 'el-input',
            maxlength: 20
          },
          {
            label: '角色类型',
            prop: 'roleType',
            component: 'el-radio-group',
            type: 'radio',
            list: 'roleTypeList'
          },
          {
            label: '业务应用',
            prop: 'followApp',
            type: 'select-arr',
            list: 'appList',
            component: 'el-select',
            arrLabel: 'appName',
            arrKey: 'appCode',
            rules: () => {
              if (this.config.formData.roleType && this.config.formData.roleType === 2) {
                return this.config.rules.followApp
              } else {
                setTimeout(() => {
                  this.config.ref.clearValidate(['followApp'])
                }, 0)
                return [{ required: false }]
              }
            }
          },
          {
            label: '描述',
            prop: 'remark',
            type: 'textarea',
            component: 'el-input',
            widthSize: 1,
            maxlength: 50
          }
        ],
        rules: {
          roleCode: [
            { required: true,
              trigger: 'blur',
              validator: (rule, value, callback) => {
                if (!value) {
                  callback(new Error('请输入角色编码'))
                } else if (!checkCode(value)) {
                  callback(new Error('不可输入空格、中文'))
                } else callback()
              }
            }
          ],
          roleName: [
            { required: true,
              trigger: 'blur',
              validator: (rule, value, callback) => {
                if (!value) {
                  callback(new Error('请输入角色名称'))
                } else if (!checkAccountName(value)) {
                  callback(new Error('不可输入特殊字符'))
                } else callback()
              } }
          ],
          roleType: [
            { required: true, message: '请选择角色类型', trigger: 'blur' }
          ],
          followApp: [
            { required: true, message: '请选择业务应用', trigger: 'blur' }
          ]
        },
        operatorList: [],
        // 相关列表
        listTypeInfo: {
          roleTypeList: [
            { label: '平台角色', value: 1 },
            { label: '三方应用角色', value: 2 }
          ],
          appList: this.appList
        }
      },

      selectNodeIds: '',
      // nodes: [],
      selectData: [],
      selectedOrg: []
    }
  },
  computed: {
    themeActive() {
      return this.$store.state.settings.theme
    }
  },
  watch: {
    'config.formData.roleType': function (newValue, oldValue) {
      this.columnProps.roleType = newValue
      this.scopeColumnProps.roleType = newValue
      if (newValue === 2) {
        this.$refs.treeTransfer.dataLeft = []
        this.clearRight()
      } else {
        this.$refs.treeTransfer.handleInit()
        this.config.formData.followApp = ''
        this.clearRight()
      }
      this.getAppList()
    },
    'config.formData.followApp': function (newValue, oldValue) {
      this.columnProps.followApp = newValue
      this.scopeColumnProps.followApp = newValue
      if (newValue || (this.config.formData.roleType === 1 && !newValue)) {
        this.$refs.treeTransfer.handleInit()
        this.clearRight()
      }
      if (this.config.formData.roleType === 2 && !newValue) {
        this.$refs.treeTransfer.dataLeft = []
        this.clearRight()
      }
    },
    'config.formData.roleId': function (newValue, oldValue) {
      this.columnProps.roleId = newValue
      this.$refs.treeTransfer.handleInit()
    }
  },
  created() {
    this.getAppList()
  },
  methods: {
    getAppList() {
      if (this.config.formData.roleType) {
        getCurrAdminGroupApps({ roleType: this.config.formData.roleType }).then((res) => {
          this.config.listTypeInfo.appList = res.data
        })
      }
    },
    clearRight() {
      this.$refs.treeTransfer.dataRight = []
      this.selectData = []
      this.grantAppIds = []
      this.grantMenuCodes = []
      this.grantMenuButtonCodes = []
      this.grantFuncionCodes = []
      this.$refs.treeTransfer.allChecked = false
      this.$refs.treeTransfer.isIndeterminate = false
    },
    openDrawer(type, data) {
      this.drawer = true
      this.dialogStatus = type
      if (type === 'create') {
        this.config.formData.roleCode = uuId(8)
        this.config.columns[0].disabled = false
        this.$nextTick(() => {
          this.clearRight()
          this.$refs.treeTransfer.handleInit()
        })
      } else {
        userDetail({ roleId: data.roleId }).then(async (res) => {
          this.config.formData = res.data
          if (res.data.sysAcRoleGrantOrgs && res.data.sysAcRoleGrantOrgs.length > 0) {
            this.selectedOrg = res.data.sysAcRoleGrantOrgs.map((item) => {
              return { id: item.grantOrgId, name: item.grantOrgName, orgPids: item.orgPids }
            })
            this.config.formData.grantOrgScopeIds = res.data.sysAcRoleGrantOrgs.map((item) => {
              return item.grantOrgId
            }).join(',')
          }
          if (type === 'update') {
            this.config.columns[0].disabled = true
          } else {
            this.config.columns[0].disabled = false
            this.config.formData.roleId = ''
            this.config.formData.roleName = ''
            this.config.formData.roleCode = uuId(8)
            this.config.formData.remark = ''
          }
          await this.getSelectNodes(data.roleId)
        })
      }
    },
    getSelectNodes(roleId) {
      getRoleFunctionChooseTree({ roleId }).then(async (res) => {
        // this.nodes = res.data
        this.selectData = res.data
        await this.handleGetChecked(res.data, '')
        this.$refs.treeTransfer.handleInit()
      })
    },
    handleEvent(type, val, item) {
      if (item.component === 'el-radio-group' && item.prop === 'roleType') {
        this.columnProps.roleType = val
        this.scopeColumnProps.roleType = val
        if (val === 1) {
          this.$refs.treeTransfer.handleInit()
        } else {
          this.$refs.treeTransfer.dataLeft = []
        }
        this.config.formData.followApp = ''
        this.clearRight()
        this.getAppList()
      }
      if (item.component === 'el-select' && item.prop === 'followApp') {
        this.clearRight()
      }
    },
    handleClose() {
      this.$confirm('取消后，您的设置将不会保存')
        .then((_) => {
          this.drawer = false
          this.resetForm()
        })
        .catch((_) => {})
    },
    permissionUpDown(val) {
      this.activePermission = !val
    },
    scopeUpDown(val) {
      this.activeScope = !val
    },
    changeRadio(val) {
      if (val === 4) {
        this.$refs.orgPicker.initTree()
      }
    },
    handleInput() {
    },
    handleGetChecked(nodes, type) {
      if (type === 'change') {
        this.grantAppIds = []
        this.grantMenuCodes = []
        this.grantMenuButtonCodes = []
        this.grantFuncionCodes = []
      }
      if (nodes && nodes.length > 0) {
        nodes.map((item) => {
          switch (item.levelType) {
            case 1:
              this.grantAppIds.push(item.id)
              break
            case 2:
              this.grantMenuCodes.push(item.menuCode)
              break
            case 3:
              this.grantMenuButtonCodes.push(item.buttonCode)
              break
            case 4:
              this.grantFuncionCodes.push(item.functionCode)
              break
          }
          if (type === '') {
            if (item.children && item.children.length > 0) {
              this.handleGetChecked(item.children, '')
            }
          }
        })
      }
    },
    // 提交form表单
    submitForm() {
      this.config.ref.validate((valid) => {
        if (!valid) return
        this.config.formData.grantAppIds = [...new Set(this.grantAppIds)].join(',')
        this.config.formData.grantMenuCodes = [...new Set(this.grantMenuCodes)].join(',')
        this.config.formData.grantMenuButtonCodes = [...new Set(this.grantMenuButtonCodes)].join(',')
        this.config.formData.grantFuncionCodes = [...new Set(this.grantFuncionCodes)].join(',')
        if (!this.$refs.treeTransfer.dataRight && this.$refs.treeTransfer.dataRight.length <= 0) {
          this.$dtMessage({
            message: '请选择角色权限',
            type: 'error'
          })
          return false
        }
        if (this.config.formData.scopeType === 4 && !this.config.formData.grantOrgScopeIds) {
          this.$dtMessage({
            message: '请选择数据范围',
            type: 'error'
          })
          return false
        }
        const fun = this.dialogStatus === 'update' ? updateRole : addRole
        fun(this.config.formData).then((res) => {
          this.$dtMessage({
            message: this.dialogStatus === 'create' ? '新增成功' : this.dialogStatus === 'update' ? '修改成功' : '复制成功',
            type: 'success'
          })
          if (this.dialogStatus === 'update') {
            // this.$parent.$parent.$parent.$parent.$parent.$parent.$parent.$refs.roleRef.getList(1)
            this.$emit('getRoleList', 1)
          } else {
            this.$parent.getList(1)
          }
          this.resetForm()
          this.drawer = false
        })
      })
    },
    // 重置form表单
    resetForm() {
      // 重置form表单
      Object.assign(
        this.$data.config.formData,
        this.$options.data().config.formData
      )
      this.config.ref?.resetFields()
      // this.nodes = []
      this.selectNodeIds = ''
      this.activePermission = false
      this.activeScope = false
      this.$refs.treeTransfer.dataRight = []
      this.grantAppIds = []
      this.grantMenuCodes = []
      this.grantMenuButtonCodes = []
      this.grantFuncionCodes = []
      this.scopeColumnProps = {
        roleId: '',
        roleName: '',
        orgId: '-1'
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.el-tabs--border-card {
  box-shadow: none;
}
  .roleInfo{
    margin: 0 24px;
    .titleBox{
      display: flex;
      justify-content: space-between;
      margin-bottom: 24px;
      border-bottom: 1px solid #DCDFE6;
      .title-text{
      font-size: 16px;
      color: #131414;
      margin-bottom: 12px;
      .title-icon{
        width: 14px;
        height: 12px;
        color: var(--themecolor);
        margin-right: 6px;
      }
    }
    .toolBtn{
      font-size: 12px;
      color: var(--themecolor) !important;
      margin-right: 8px;
      cursor: pointer;
    }
    }
    .scope-remark{
      margin-top: 16px;
      height: 20px;
      font-size: 12px;
      font-family: HarmonyOS Sans SC-Regular, HarmonyOS Sans SC;
      font-weight: 400;
      color: #909399;
      line-height: 20px;
    }
  }
  .btn{
    margin: 20px 24px;
    display: flex;
    justify-content: flex-end;
  }
</style>
